	package com.ternnetwork.core.accesscontroll.service.impl;
	
	import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.HashSet;
	import java.util.List;
	import java.util.Set;
	
	import org.springframework.beans.factory.annotation.Autowired;
	import org.springframework.stereotype.Service;
	import org.springframework.transaction.annotation.Propagation;
	import org.springframework.transaction.annotation.Transactional;
	import org.springframework.util.StringUtils;
	
	import com.ternnetwork.commons.model.http.BaseResponse;
	import com.ternnetwork.core.accesscontroll.entity.RescRole;
	import com.ternnetwork.core.accesscontroll.entity.RescRoleId;
	import com.ternnetwork.core.accesscontroll.entity.Resources;
	import com.ternnetwork.core.accesscontroll.entity.Role;
	import com.ternnetwork.core.accesscontroll.enums.ResourcesType;
	import com.ternnetwork.core.accesscontroll.enums.messages.DepartmentMessages;
	import com.ternnetwork.core.accesscontroll.enums.messages.ResourcesMessages;
	import com.ternnetwork.core.accesscontroll.repository.ResourcesRepository;
	import com.ternnetwork.core.accesscontroll.service.RescRoleService;
	import com.ternnetwork.core.accesscontroll.service.ResourcesService;
	import com.ternnetwork.core.accesscontroll.vo.CheckBoxResourcesZtree;
	import com.ternnetwork.core.accesscontroll.vo.ResourcesZtree;
	
	
	
	@Service
	public class ResourcesServiceImpl implements ResourcesService {

		private final ResourcesRepository resourcesRepository;

		private final RescRoleService rescRoleService;

		public ResourcesServiceImpl(ResourcesRepository resourcesRepository, RescRoleService rescRoleService) {
			this.resourcesRepository = resourcesRepository;
			this.rescRoleService = rescRoleService;
		}

		@Override
		@Transactional(propagation = Propagation.REQUIRES_NEW,rollbackFor=Exception.class)
		public BaseResponse add(Resources t) {
    	
	    	BaseResponse  baseResponse=checkProperties(t);
	    	
	    	if(baseResponse.getStatus().intValue()==0) {
	    		return baseResponse;
	    	}
	    	
	    	
	    	if(!StringUtils.isEmpty(t.getNameEn())) {
	    		
	    		long totalCount=resourcesRepository.getCountByCode(t.getNameEn()); 
		    	
		      	if(totalCount>0L) {
		    		baseResponse.setFailed(ResourcesMessages.FAILED_MESSAGE_CODE_CAN_NOT_BE_DUPLICATE.getName());
		    		return baseResponse;
		    	}
	    	}
	    	
	      
	    	
	    	resourcesRepository.saveAndFlush(t);
			
	    	setRescRoleByRoleIds(t);
	    	
			baseResponse.setSccucess(t);
			
			return baseResponse;
		}
		
		@Override
		@Transactional(propagation = Propagation.REQUIRES_NEW,rollbackFor=Exception.class)
	    public BaseResponse update(Resources t) {
		   	 
	        BaseResponse  baseResponse=checkProperties(t);
	    	//校验不通过
	    	if(baseResponse.getStatus().intValue()==0) {
	    		return baseResponse;
	    	}
	    	
	    	if(!StringUtils.isEmpty(t.getNameEn())) {
	    	
		    	long totalCount=resourcesRepository.getCountByCodeAndExcludeId(t.getNameEn().toUpperCase(), t.getId()); 
		    	
		      	if(totalCount>0L) {
		    		baseResponse.setFailed(ResourcesMessages.FAILED_MESSAGE_CODE_CAN_NOT_BE_DUPLICATE.getName());
		    		return baseResponse;
		    	}
		      	
	    	}
	      	Resources old=resourcesRepository.getOne(t.getId());
	    	
	    	if(old==null||old.getId().longValue()==0L) {
	    		baseResponse.setFailedForObjectNotExist();
	    		return baseResponse;
	    	}
	    	
	    	old.setNameZh(t.getNameZh());
	    	
	    	if(!StringUtils.isEmpty(t.getNameEn())) {
	    		old.setNameEn(t.getNameEn().toUpperCase());
	    	}
		
			old.setSeqNum(t.getSeqNum());
			old.setUrl(t.getUrl());
			old.setRemark(t.getRemark());
			old.setIconCls(t.getIconCls());
			old.setParentId(t.getParentId());
	   		resourcesRepository.saveAndFlush(old);
	   		//当有资源与关联的角色有变化的时候
	   		if(!compareRoleIds(t.getRoleIds(),old.getRoleIds())) {
	   			rescRoleService.deleteBatch(t.getId(), t.getDeleteRoleIds());
				rescRoleService.addBatch(t.getId(), t.getRoleIds());
	   		}
	  			baseResponse.setSccucess(t);
			return baseResponse;
		}
		
		private Boolean compareRoleIds(String roleIds,String roleIdsToCompare) {
			if(roleIds.equals(roleIdsToCompare)) {
				return true;
			}
			String[] roleIdsArray=roleIds.split(",");
			String[] roleIdsToCompareArray=roleIdsToCompare.split(",");
			Arrays.sort(roleIdsArray);
	    	Arrays.sort(roleIdsToCompareArray);
	   		return Arrays.equals(roleIdsArray, roleIdsToCompareArray);
		}
		
		@Override
	    @Transactional(propagation = Propagation.REQUIRES_NEW,rollbackFor=Exception.class)
	    public BaseResponse deleteById(Long id) {
			
			BaseResponse  baseResponse=new BaseResponse();
			
			Resources old=resourcesRepository.getOne(id);
			
			if(old==null||old.getId().longValue()==0L) {
	    		baseResponse.setFailedForObjectNotExist();
	    		return baseResponse;
	    	}
			
			long totalCount=resourcesRepository.getCountByParentId(id);
			
			if(totalCount>0L) {
	    		baseResponse.setFailed(DepartmentMessages.FAILED_MESSAGE_EXIST_CHILDREN.getName());
	    		return baseResponse;
	    	}
			resourcesRepository.delete(old);
			
			baseResponse.setSccucess();
			
			return baseResponse;
		}
		
	    
		@Override
	    public BaseResponse getZtreeJson(ResourcesType resourcesType){
			List<Resources> list=resourcesRepository.findAll(resourcesType);
			List<ResourcesZtree> treeList = convertToZtreeList(list);
			BaseResponse resoponse=new BaseResponse();
			resoponse.setSccucess(treeList);
			return resoponse;
		}
	    
		@Override
	    public BaseResponse getZtreeJson(ResourcesType resourcesType,String userName){
	  		List<Resources> list=resourcesRepository.findAll(resourcesType,userName);
	  		List<ResourcesZtree> treeList = convertToZtreeList(list);
	  		BaseResponse resoponse=new BaseResponse();
	  		resoponse.setSccucess(treeList);
	  		return resoponse;
	  	}
		@Override
	    public BaseResponse getAllWithCheckBoxZtreeJson(ResourcesType resourcesType,Long roleId){
	  		
	  		List<Resources> allList=resourcesRepository.findAll(resourcesType);
	
			List<Resources> roleReslist=resourcesRepository.findAll(resourcesType,roleId);
			
			List<CheckBoxResourcesZtree> ztreeList = convertToZtreeList(allList,roleReslist);
	
			BaseResponse resoponse=new BaseResponse();
			
	  		resoponse.setSccucess(ztreeList);
	  		
	  		return resoponse;
	  	}
	    
	     private List<ResourcesZtree> convertToZtreeList(List<Resources> list) {
			List<ResourcesZtree> retVal=new ArrayList<ResourcesZtree>();
			for(int i=0;i<list.size();i++){
				Resources t=list.get(i);
				ResourcesZtree tree=new ResourcesZtree();
				tree.setId(t.getId());
				tree.setpId(t.getParentId());
				tree.setName(t.getNameZh());
				tree.setNameZh(t.getNameZh());
				tree.setNameEn(t.getNameEn());
				tree.setUrl(t.getUrl());
				tree.setType(t.getType());
				tree.setSeqNum(t.getSeqNum());
				String[] roleIds=t.getRoleIds().equals("")?new String[]{}:t.getRoleIds().split(",");
				tree.setRoleIds(roleIds);
				retVal.add(tree);
			}
			return retVal;
		}
		
		 /**
		  * 检查属性
		  * @param t
		  * @return
		  */
		 private BaseResponse checkProperties (Resources t) {
		  	 
			if(!StringUtils.isEmpty(t.getNameEn())) {
	      		t.setNameEn(t.getNameEn().toUpperCase());
	      	}else {
	      		t.setNameEn(null);
	      	}
			
			BaseResponse  baseResponse=new BaseResponse();
		    if(StringUtils.isEmpty(t.getNameZh())) {
		    	baseResponse.setFailed(ResourcesMessages.FAILED_MESSAGE_NAME_ZH_CAN_NOT_BE_EMPTY.getName());
		    	return baseResponse;
		    }
		    baseResponse.setSccucess();
		    return baseResponse;
		   
		 }
		
		
		 private Resources setRescRoleByRoleIds(Resources t) {
				Set<RescRole> rescRoles=new HashSet<RescRole>();
				String[] roleIdsArray=t.getRoleIds().equals("")?new String[]{}:t.getRoleIds().split(",");
				for(String roleId:roleIdsArray){
					Role r=new Role();
					r.setId(Long.parseLong(roleId));
					RescRole ur=new RescRole();
					ur.setRole(r);
					ur.setResources(t);
					RescRoleId id=new RescRoleId();
					id.setRoleId(r.getId());
					id.setResourcesId(t.getId());
					ur.setId(id);
					rescRoles.add(ur);
				}
				t.setRescRoles(rescRoles);;
				return t;
			}
		 
	
			
			
			
			private List<CheckBoxResourcesZtree> convertToZtreeList(List<Resources> allList,List<Resources> roleReslist) {
				List<CheckBoxResourcesZtree> retVal=new ArrayList<CheckBoxResourcesZtree>();
				for(Resources t:allList){
					CheckBoxResourcesZtree tree=new CheckBoxResourcesZtree();
					tree.setId(t.getId());
					tree.setpId(t.getParentId());
					tree.setName(t.getNameZh());
					tree.setNameZh(t.getNameZh());
					tree.setNameEn(t.getNameEn());
					tree.setUrl(t.getUrl());
					tree.setType(t.getType());
					tree.setSeqNum(t.getSeqNum());
					String[] roleIds=t.getRoleIds().equals("")?new String[]{}:t.getRoleIds().split(",");
					tree.setRoleIds(roleIds);
					tree.setChecked(checkExist(t.getId(),roleReslist));
					retVal.add(tree);
				}
				return retVal;
			}
			
			private Boolean checkExist(long resourcesId,List<Resources> roleReslist){
				for(Resources t:roleReslist){
					if(t.getId()==resourcesId){
						return true;
					}
				}
				return false;
			}
	
		
		
		
	
	}
